package com.iotechn.unimall.admin.api.integral;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.iotechn.unimall.core.exception.AdminServiceException;
import com.iotechn.unimall.core.exception.ExceptionDefinition;
import com.iotechn.unimall.core.exception.ServiceException;
import com.iotechn.unimall.data.domain.CouponDO;
import com.iotechn.unimall.data.domain.IntegralGoodsDO;
import com.iotechn.unimall.data.domain.SkuDO;
import com.iotechn.unimall.data.domain.SpuDO;
import com.iotechn.unimall.data.dto.goods.SpuDTO;
import com.iotechn.unimall.data.dto.integralactivity.IntegralGoodsAppDTO;
import com.iotechn.unimall.data.enums.IntegralGoodsStatusType;
import com.iotechn.unimall.data.enums.IntegralGoodsType;
import com.iotechn.unimall.data.mapper.CouponMapper;
import com.iotechn.unimall.data.mapper.IntegralGoodsMapper;
import com.iotechn.unimall.data.mapper.SkuMapper;
import com.iotechn.unimall.data.mapper.SpuMapper;
import com.iotechn.unimall.data.model.Page;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author kyms
 * @date 2020-07-31 17:39
 */
@Service
public class AdminIntegralGoodsServiceImpl implements AdminIntegralGoodsService {
    @Autowired
    private IntegralGoodsMapper integralGoodsMapper;

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private CouponMapper couponMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public IntegralGoodsDO addIntegralGoods(IntegralGoodsDO integralGoodsDO, Long adminId) throws ServiceException {
        Date now = new Date();
        integralGoodsDO.setAdminId(adminId);
        integralGoodsDO.setGmtCreate(now);
        integralGoodsDO.setGmtUpdate(now);
        if (integralGoodsDO.getConponId() != null && integralGoodsDO.getConponId() > 0L) {
            integralGoodsDO.setSkuId(0L);
            integralGoodsDO.setSpuId(0L);
            CouponDO couponDO = couponMapper.selectById(integralGoodsDO.getConponId());
            if(couponDO != null){
                integralGoodsDO.setGoodsName(couponDO.getTitle());
            }
        } else {
            integralGoodsDO.setConponId(0L);
        }
        if(integralGoodsDO.getGoodsType().intValue() == IntegralGoodsType.EXCHANGETURNTAB.getCode()) {
            integralGoodsDO.setGoodsName(IntegralGoodsType.EXCHANGETURNTAB.getMsg());
        }
        integralGoodsMapper.insert(integralGoodsDO);
        return integralGoodsDO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public IntegralGoodsDO updateIntegralGoods(IntegralGoodsDO integralGoodsDO, Long adminId) throws ServiceException {
        if (integralGoodsDO == null || integralGoodsDO.getId() == null) {
            throw new AdminServiceException(ExceptionDefinition.PARAM_CHECK_FAILED);
        }
        if (integralGoodsDO.getConponId() != null && integralGoodsDO.getConponId() > 0L) {
            integralGoodsDO.setSkuId(0L);
            integralGoodsDO.setSpuId(0L);
        } else {
            integralGoodsDO.setConponId(0L);
        }
        Date now = new Date();
        integralGoodsDO.setAdminId(adminId);
        integralGoodsDO.setGmtUpdate(now);
        integralGoodsMapper.updateById(integralGoodsDO);
        return integralGoodsDO;
    }

    @Override
    public Page<IntegralGoodsDO> pageIntegralGoods(Integer page, Integer limit, String search, Integer type, String startTime, String endTime, Integer status, Long adminId) throws ServiceException {
        Wrapper<IntegralGoodsDO> wrapper = new EntityWrapper<IntegralGoodsDO>();
//搜索商品名称/条码
        List<Long> skuIds = new ArrayList<>();
        List<Long> spuIds = new ArrayList<>();
        List<Long> couponIds = new ArrayList<>();
        if (!StringUtils.isEmpty(search)) {
            List<SpuDO> spuDOS = spuMapper.selectList(new EntityWrapper<SpuDO>().like("title", search));

            List<SkuDO> skus = skuMapper.selectList(new EntityWrapper<SkuDO>().like("title", search)
                    .or().like("bar_code", search));

            //skuid
            if (!CollectionUtils.isEmpty(skus)) {
                skuIds = skus.stream().map(SkuDO::getId).collect(Collectors.toList());
            }
            //spuId
            if (!CollectionUtils.isEmpty(spuIds)) {
                spuIds = spuDOS.stream().map(SpuDO::getId).collect(Collectors.toList());
            }
            //优惠券
            List<CouponDO> coupons = couponMapper.selectList(new EntityWrapper<CouponDO>().eq("type", 4).like("title", search));

            if (!CollectionUtils.isEmpty(coupons)) {
                couponIds = coupons.stream().map(CouponDO::getId).collect(Collectors.toList());
            }
        }

        //时间范围搜索
        if (!StringUtils.isEmpty(startTime)) {
            wrapper.gt("gmt_create", startTime);
        }
        if (!StringUtils.isEmpty(endTime)) {
            wrapper.le("gmt_create", endTime);
        }

        if (type != null) {
            wrapper.eq("type", type);
        }
        if (status != null) {
            wrapper.eq("status", type);
        }
        if (!CollectionUtils.isEmpty(spuIds)) {
            wrapper.or().in("spu_id", spuIds);
        }
        if (!CollectionUtils.isEmpty(skuIds)) {
            wrapper.or().in("sku_id", skuIds);
        }
        if (!CollectionUtils.isEmpty(couponIds)) {
            wrapper.or().in("conpon_id", couponIds);
        }

        wrapper.orderBy("id", false);
        Integer count = integralGoodsMapper.selectCount(wrapper);
        List<IntegralGoodsDO> integralGoodsDOS = integralGoodsMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
        integralGoodsDOS = integralGoodsDOS.stream().map(item -> {
            if (item.getSkuId() != null && item.getSkuId() > 0L) {
                StringBuffer sbf = new StringBuffer();
                SpuDO spuDO = spuMapper.selectById(item.getSpuId());
                if (spuDO != null && !StringUtils.isEmpty(spuDO.getTitle())) {
                    sbf.append(spuDO.getTitle() + " ");
                }
                SkuDO skuDO = skuMapper.selectById(item.getSkuId());
                if (skuDO != null && !StringUtils.isEmpty(skuDO.getTitle())) {

                    sbf.append(" " + skuDO.getTitle());
                }
                item.setGoodsName(sbf.toString());
            } else {
                if (item.getConponId() != null && item.getConponId() > 0L) {
                    CouponDO couponDO = couponMapper.selectById(item.getConponId());
                    if (couponDO != null && !StringUtils.isEmpty(couponDO.getTitle())) {
                        item.setGoodsName(couponDO.getTitle());
                    } else {
                        item.setGoodsName("");
                    }
                }
            }
            return item;
        }).collect(Collectors.toList());
        return new Page<>(integralGoodsDOS, page, limit, count);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public IntegralGoodsDO shelveIntegralGoods(Long id, Integer status, Long adminId) throws ServiceException {
        if (id == null || id <= 0L) {
            throw new AdminServiceException(ExceptionDefinition.PARAM_CHECK_FAILED);
        }
        Date now = new Date();
        IntegralGoodsDO integralGoodsDO = new IntegralGoodsDO();
        integralGoodsDO.setId(id);
        integralGoodsDO.setAdminId(adminId);
        integralGoodsDO.setGmtUpdate(now);
        integralGoodsDO.setStatus(status);
        integralGoodsMapper.updateById(integralGoodsDO);
        return integralGoodsDO;
    }

    @Override
    public List<SkuDO> searchSku(String search, Long adminId) {
        List<SpuDTO> spus = spuMapper.searchSpu(search, 1);
        List<SkuDO> skus = new LinkedList<>();
        spus.forEach(item -> {
            List<SkuDO> s = skuMapper.selectList(new EntityWrapper<SkuDO>().eq("spu_id", item.getId()).orderBy("id", false));
            s = s.stream().map(i -> {
                i.setSpuskutitle(item.getTitle());
                return i;
            }).collect(Collectors.toList());
            skus.addAll(s);
        });

        return CollectionUtils.isEmpty(skus) ? new LinkedList<>() : skus;
    }

    @Override
    public List<SkuDO> listCouponAsSku(Integer status, Long adminId) {
        List<CouponDO> coupons = couponMapper.selectList(new EntityWrapper<CouponDO>().eq("type", 4));
        List<SkuDO> skuDOS = new LinkedList<>();
        if (!CollectionUtils.isEmpty(coupons)) {
            skuDOS = coupons.stream().map(item -> {
                SkuDO skuDO = new SkuDO();
                skuDO.setSpuskutitle(item.getTitle());
                skuDO.setId(item.getId());
                skuDO.setStock(item.getTotal() == null ? 0 : item.getTotal().floatValue());
                return skuDO;
            }).collect(Collectors.toList());
        }
        return skuDOS;
    }

    @Override
    public SkuDO detailGoods(Long id, Long adminId) {
        return skuMapper.selectById(id);
    }

    @Override
    public IntegralGoodsAppDTO detail(Long id, Long adminId) throws ServiceException {
        IntegralGoodsAppDTO integralGoodsAppDTO = new IntegralGoodsAppDTO();
        integralGoodsAppDTO.setSpuDO(new SpuDO());
        integralGoodsAppDTO.setSkuDO(new SkuDO());
        integralGoodsAppDTO.setIntegralGoods(new IntegralGoodsDO());
        IntegralGoodsDO integralGoodsDO = integralGoodsMapper.selectById(id);
        if (integralGoodsDO != null) {
            if (integralGoodsDO.getGoodsType().intValue() == IntegralGoodsType.EXCHANGECOUPON.getCode()) {
                CouponDO couponDO = couponMapper.selectById(integralGoodsDO.getConponId());
                if (couponDO != null) {
                    SkuDO skuDO = new SkuDO();
                    SpuDO spuDO = new SpuDO();
                    spuDO.setTitle("");
                    skuDO.setTitle(couponDO.getTitle());
                    skuDO.setVipPrice(0);
                    skuDO.setPrice(0);
                    skuDO.setOriginalPrice(0);
                    skuDO.setStock(couponDO.getTotal().floatValue());
                    integralGoodsAppDTO.setSkuDO(skuDO);
                    integralGoodsAppDTO.setSpuDO(spuDO);
                }
            }
            if(integralGoodsDO.getGoodsType().intValue() == IntegralGoodsType.EXCHANGEGOOD.getCode()) {
                SkuDO skuDO = skuMapper.selectById(integralGoodsDO.getSkuId());
                if (skuDO != null) {
                    integralGoodsAppDTO.setSkuDO(skuDO);
                }
                SpuDO spuDO = spuMapper.selectById(integralGoodsDO.getSpuId());
                if (spuDO != null) {
                    integralGoodsAppDTO.setSpuDO(spuDO);
                }
                integralGoodsDO.setGoodsType(IntegralGoodsType.EXCHANGEGOOD.getCode());
            }
            integralGoodsAppDTO.setIntegralGoods(integralGoodsDO);
        }

        return integralGoodsAppDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public IntegralGoodsDO start(Long id, Long adminId) throws ServiceException {
        if (id == null || id <= 0L) {
            throw new AdminServiceException(ExceptionDefinition.PARAM_CHECK_FAILED);
        }
        Date now = new Date();
        IntegralGoodsDO integralGoodsDO = new IntegralGoodsDO();
        integralGoodsDO.setId(id);
        integralGoodsDO.setAdminId(adminId);
        integralGoodsDO.setGmtUpdate(now);
        integralGoodsDO.setStatus(IntegralGoodsStatusType.START.getCode());//开启
        integralGoodsMapper.updateById(integralGoodsDO);
        return integralGoodsDO;
    }

    @Override
    public Integer checkCoupon(Long couponId) throws ServiceException {
        Wrapper<IntegralGoodsDO> coupponWrapper = new EntityWrapper<IntegralGoodsDO>();
        coupponWrapper.eq("goods_type",IntegralGoodsType.EXCHANGECOUPON.getCode());
        coupponWrapper.eq("conpon_id",couponId);
        Integer integer = integralGoodsMapper.selectCount(coupponWrapper);
        return integer;
    }
}
